<template>
  <div :class="{ 'wms-pagination--hidden': hidden }" class="wms-pagination">
    <el-pagination
      :background="background"
      v-model:current-page="currentPage"
      v-model:page-size="pageSize"
      :layout="layout"
      :page-sizes="pageSizes"
      :pager-count="pagerCount"
      :total="total"
      :small="small"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<script setup lang="ts">
import { computed } from "vue";

/**
 * WMS分页组件属性接口
 */
interface WmsPaginationProps {
  /** 总记录数 */
  total: number;
  /** 当前页码 */
  page?: number;
  /** 每页显示条数 */
  limit?: number;
  /** 每页显示个数选择器的选项设置 */
  pageSizes?: number[];
  /** 设置最大页码按钮数 */
  pagerCount?: number;
  /** 组件布局，子组件名用逗号分隔 */
  layout?: string;
  /** 是否为分页按钮添加背景色 */
  background?: boolean;
  /** 是否使用小型分页样式 */
  small?: boolean;
  /** 是否自动滚动到顶部 */
  autoScroll?: boolean;
  /** 是否隐藏分页器 */
  hidden?: boolean;
}

/**
 * WMS分页组件事件接口
 */
interface WmsPaginationEmits {
  /** 页码更新事件 */
  "update:page": [page: number];
  /** 每页条数更新事件 */
  "update:limit": [limit: number];
  /** 分页变化事件 */
  pagination: [params: { page: number; limit: number }];
}

// 组件属性定义
const props = withDefaults(defineProps<WmsPaginationProps>(), {
  page: 1,
  limit: 20,
  pageSizes: () => [10, 20, 30, 50],
  pagerCount: () => (document.body.clientWidth < 992 ? 5 : 7),
  layout: "total, sizes, prev, pager, next, jumper",
  background: true,
  small: false,
  autoScroll: true,
  hidden: false,
});

// 组件事件定义
const emit = defineEmits<WmsPaginationEmits>();

// 当前页码双向绑定
const currentPage = computed({
  get() {
    return props.page;
  },
  set(val: number) {
    emit("update:page", val);
  },
});

// 每页条数双向绑定
const pageSize = computed({
  get() {
    return props.limit;
  },
  set(val: number) {
    emit("update:limit", val);
  },
});

/**
 * 每页条数变化处理
 * @param val 新的每页条数
 */
function handleSizeChange(val: number): void {
  // 如果当前页 * 新的每页条数 > 总数，则重置到第一页
  if (currentPage.value * val > props.total) {
    currentPage.value = 1;
  }

  emit("pagination", { page: currentPage.value, limit: val });

  // 自动滚动到页面顶部
  if (props.autoScroll) {
    scrollToTop();
  }
}

/**
 * 当前页码变化处理
 * @param val 新的页码
 */
function handleCurrentChange(val: number): void {
  emit("pagination", { page: val, limit: pageSize.value });

  // 自动滚动到页面顶部
  if (props.autoScroll) {
    scrollToTop();
  }
}

/**
 * 滚动到页面顶部
 * @param duration 滚动动画持续时间(ms)
 */
function scrollToTop(duration: number = 800): void {
  const start = window.pageYOffset;
  const startTime = performance.now();

  function scroll(currentTime: number): void {
    const elapsed = currentTime - startTime;
    const progress = Math.min(elapsed / duration, 1);

    // 使用缓动函数
    const easeInOutCubic = (t: number): number =>
      t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;

    window.scrollTo(0, start * (1 - easeInOutCubic(progress)));

    if (progress < 1) {
      requestAnimationFrame(scroll);
    }
  }

  requestAnimationFrame(scroll);
}
</script>

<style scoped lang="scss">
.wms-pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: var(--wms-spacing-lg) var(--wms-spacing-md);
  background-color: var(--wms-bg-white);
  border-top: 1px solid var(--wms-border-color-light);

  &--hidden {
    display: none;
  }

  // 响应式适配
  @media (max-width: 768px) {
    padding: var(--wms-spacing-md) var(--wms-spacing-sm);

    :deep(.el-pagination) {
      .el-pagination__total,
      .el-pagination__sizes {
        display: none;
      }
    }
  }

  // 暗色主题适配
  @media (prefers-color-scheme: dark) {
    background-color: var(--wms-bg-dark);
    border-top-color: var(--wms-border-color-dark);
  }
}

// Element Plus分页组件样式定制
:deep(.el-pagination) {
  .el-pager li {
    &.is-active {
      background-color: var(--wms-primary-color);
      color: var(--wms-text-color-white);
    }

    &:hover:not(.is-active) {
      background-color: var(--wms-primary-color-light);
    }
  }

  .btn-prev,
  .btn-next {
    &:hover:not(.is-disabled) {
      color: var(--wms-primary-color);
    }
  }

  .el-pagination__sizes .el-select .el-select__wrapper {
    border-color: var(--wms-border-color);

    &:hover {
      border-color: var(--wms-primary-color);
    }
  }
}
</style>
